#lang racket

; 1. Create: make-parameter creates a dynamic-binding variable

; (define x (make-parameter 1))
; (printf "~a\n" x) ; #<procedure:parameter-procedure>

; 2. Read: (x) reads a dynamic-binding variable

;(printf "Initial: ~a\n" (x)) ; 1

; 3. Write: parameterize writes a dynamic-binding variable
#|
(define (f)
  (printf "(f) Before: ~a\n" (x)) ; x
  (parameterize ([x (+ (x) 1)])
    (printf "(f) Inside parameterize: ~a\n" (x))) ; x + 1
  (printf "(f) After: ~a\n" (x))) ; x


(parameterize ([x 99])
  (f) ; 99, 100, 99
  (printf "Inside parameterize: ~a\n" (x))) ; 99

(printf "After parameterize: ~a\n" (x)) ; 1
|#









; ---------
; Example 2
#|
; NOT VALID RACKET CODE
(define x 1)
(define (f y) (+ y x))
(define (g)
  (define x 20)
  (define y 3)
  (f (+ x y)))
; NOT VALID RACKET CODE
(check-equal? (g) (+ 23 20))
|#

#|
(define x (make-parameter 1))

(define (f y)
  (+ y (x)))

(define (g)
  (parameterize ([x 20])
    (define y 3)
    (f (+ (x) y))))

(require rackunit)
(check-equal? (g) (+ 23 20))


(define buff (open-output-string))

#|
(fprintf buff "foo\n")
(get-output-string buff)
|#

(parameterize ([current-output-port buff])
  ; In this context, the standard output is a string buffer.
  (display "hello world!\n"))

(get-output-string buff)

|# ; End of Example 2
